import { IActorMove, IClientInput, IState, ITimePass } from "../Common/Interface/State";
import { EntityTypeEnum, G, GChapter, GSyncDelay, IRoom, InputTypeEnum, Singleton, StateTypeEnum, deepClone } from "../Common";
import { ActorManager } from "../Entity/Actor/ActorManager";
import { EnemyManager } from "../Entity/Enemy/EnemyManager";
import { WeaponManager } from "../Entity/Weapon/WeaponManager";
import { BulletManager } from "../Entity/Bullet/BulletManager";
import { BattleJoyStick } from "../UI/BattleJoyStick";
import { BattleScene } from "../Scene/BattleScene";
import { BattleSingleScene } from "../Scene/BattleSingleScene";
import QuadTree from "../Common/QuadTree";
import { GameLogic } from "../Common/Runtime/GameLogic";
import { BehaviorManager } from "../Common/BehaviorTree/BehaviorManager";
import { Simulator } from "../Common/RVO/Simulator";
import { ExpManager } from "../Entity/Exp/ExpManager";
import { RedXManager } from "../Entity/RedX/RedXManager";
import { HPBar } from "../UI/HPBar";
import { AttributeManager } from "../Common/Runtime/AttributeManager";
import { TalentManager } from "./TalentManager";
import { ScrollManager } from "../Entity/Scroll/ScrollManager";
import { SkillManager } from "../Common/Runtime/SkillManager";

export default class DataManager extends Singleton {

    defaultState: IState = {
        actors: [],
        bullets: [],
        enemyBullets: [],
        nextId: 1,
        enemies: [],
        weapons: [],
        props: [],
        enemySkills: [],
        exps: [],
        scrolls: [],
        redXs: [],
        scrollNum: 0,
        dt: 0,
        seed: 0,
        isPause: 0,
        /** 游戏倍速 */
        gameSpeed: 1,
        playerExp: 0,
        playerLevel: 1,
        state: StateTypeEnum.idle,
        enemyBuffs: [],
        skill: [],
        levelState: {
            normalLevelTime: 0,
            totalTime: 0,
            totalLevel: 0,
            levelTime: 0,
            partEnemyTime: {},
            bossArr: [],
            chapter: 1,
            level: 1,
            levelType: 0
        }
    }
    static get Ins() {
        return super.GetInstance<DataManager>()
    }

    /** 选择池 */
    selectPool: number[] = []
    HPBarMap: Map<string, HPBar> = new Map()
    actorMap: Map<number, ActorManager> = new Map()
    enemyMap: Map<number, EnemyManager> = new Map()
    weaponMap: Map<number, WeaponManager> = new Map()
    tbsjMap: Map<number, WeaponManager> = new Map()
    bulletMap: Map<number, BulletManager> = new Map()
    expBallMap: Map<number, ExpManager> = new Map()
    redXMap: Map<number, RedXManager> = new Map()
    scrollMap: Map<number, ScrollManager> = new Map()
    enemyBulletMap: Map<number, BulletManager> = new Map()
    stateMap: Map<number, IState> = new Map()
    behaviorTreeMap: Map<number, BehaviorManager> = new Map()
    simulator: Simulator

    /** 房间信息 */
    roomInfo: IRoom
    /** 单机模式 */
    isSingle: boolean = false
    /** 摇杆 */
    jm: BattleJoyStick
    /** 当前战斗场景 */
    bm: BattleScene | BattleSingleScene
    /** 四叉树 */
    quadTree: QuadTree
    /** 关卡总波数 */
    totalLevel: number
    myId = 1
    frameId = 1

    /** 延迟后的游戏渲染帧时间 */
    renderTotalTime: number

    /** 当前状态 */
    state: IState = this.defaultState

    applyInput(input: IClientInput) {

        if (input.type == InputTypeEnum.actorMove) {

            this.state = GameLogic.Ins.actorMove(input as IActorMove, this.state)
            this.state.actors[0].isMove = 1
        } else if (input.type == InputTypeEnum.timePass) {
            // this.bm.graphicsLine()

            const { state, simulator } = GameLogic.Ins.tick(input as ITimePass, this.state, this.quadTree, this.behaviorTreeMap, this.simulator)
            this.state = state
            this.simulator = simulator
            this.renderTotalTime = this.state.levelState.totalTime - (GSyncDelay / 1000)

            if (GameLogic.Ins.state.state == StateTypeEnum.lost || GameLogic.Ins.state.state == StateTypeEnum.win) return
            AttributeManager.Ins.countAttr()
            this.state.actors[0].isMove = 0
        }
    }

    initStateData() {
        this.reset()
        this.state.actors.push({
            skillPoint: 0,
            id: DataManager.Ins.myId,
            nickName: '',
            type: EntityTypeEnum.actor,
            position: { x: 0, y: 0 },
            direction: { x: 1, y: 0 },
            hp: 20,
            state: StateTypeEnum.none,
            beHitCD: 0,
            skill: [],
            regenerationCD: 0,
            deadNum: 0,
            attr: {
                hpMax: 20,
                defense: 0,
                damage: 0,
                growth: 0,
                regeneration: 0,
                knckback: 0,
                range: 0,
                fireRate: 0,
                lootRange: 0,
                critRate: 0,
                critChance: 0,
                moveSpeed: 0,
                hpMaxRate: 0,
                defenseRate: 0,
                damageRate: 0,
                weaponNumber: 0,
                propNumber: 0,
                penetrate: 0,
                startExp: 0,
                rebornNum: 0,
            },
            isMove: 0
        })
        this.state.weapons.push({
            id: 1,
            owner: DataManager.Ins.myId,
            entityType: EntityTypeEnum.weapon7,
            position: { x: 0, y: 0 },
            direction: { x: 1, y: 0 },
            shootCD: 0,
            searchCD: 0,
            targetId: null,
            state: StateTypeEnum.none,
            star: 1,
        })

        let totalNum = 0
        for (const i in GChapter[this.state.levelState.chapter]) {
            totalNum++
        }
        this.state.levelState.totalLevel = totalNum

        GameLogic.Ins.setWeaponPos(DataManager.Ins.state.weapons)

        DataManager.Ins.simulator = new Simulator()

        // 构造四叉树结构
        DataManager.Ins.quadTree = new QuadTree({
            x: -G.StageSize.w / 2,
            y: -G.StageSize.h / 2,
            w: G.StageSize.w,
            h: G.StageSize.h,
        }, 1)

        GameLogic.Ins.initAgent(DataManager.Ins.simulator)
        GameLogic.Ins.setLevelData(DataManager.Ins.state)
        this.state = TalentManager.Ins.pointReplaceDefaultWeapon(this.state)
    }

    /** 重置数据 */
    reset() {

        SkillManager.Ins.reset()
        this.selectPool = []
        this.actorMap = new Map()
        this.enemyMap = new Map()
        this.weaponMap = new Map()
        this.tbsjMap = new Map()
        this.bulletMap = new Map()
        this.expBallMap = new Map()
        this.redXMap = new Map()
        this.enemyBulletMap = new Map()
        this.stateMap = new Map()
        this.behaviorTreeMap = new Map()
        this.HPBarMap = new Map()

        this.state = deepClone(this.defaultState)
    }

    /** 给角色当前生命赋值 */
    setActorHp() {
        this.state.actors[0].hp = AttributeManager.Ins.hpMax
    }

}